package uk.ac.cam.echo.reader;

import java.util.Set;

/**
 * @author Andrius Dagys
 */

public class Reader {
	/**
	 *  The configuration file is currently stored in the root directory of the
	 *  USB stick, which translates to /live/image/ for the persistent OS that
	 *  runs from it.
	 */
	private static final String configFile = "/live/image/AppSettings.txt";

	protected Client c;
	protected DBCache cache;
	protected Configuration conf;
	protected UI u;
	protected RFID1 reader;

	public boolean checkInMode() {
		return conf.isCheckInMode();
	}
	/**
	 *  Sets up connections to serial devices and the server
	 */
	Reader() {
		conf = new Configuration(Reader.configFile);
		c = new Client(conf.getServer(), conf.getPort());
		u = new UI(conf.getUiPort());
		reader = new RFID1(conf.getReaderPort());
	}

	public static void main(String[] args) {
		Reader r = new Reader();
		r.enableCache();
		//
		// Determine which mode to run in
		//
		if (r.checkInMode()) {	
			r.runCheckIn();
		} else {
			r.runSecurity();
		}
	}
	
	/**
	 *  Security mode
	 */
	public void runSecurity() {
		System.out.println("Running security mode");
		Set<String> tags;
		try {
			//
			// Monitor tags
			//
			u.bell();
			u.display("Please swipe your\r\nwristband...");

			while (true) {
				try {
					//
					// Get currently scanned tags
					//
					tags = reader.poll();
					u.display("Please wait..\r\n");

					try {
						String name = cache.getUserInfo(tags.iterator().next());
						//
						// If user found
						//
						reader.passBeep();
						u.ledGreenOn();
						u.display(name + "\r\n");

					} catch (UserNotFoundException e) {
						//
						// If user not found
						//
						reader.failBeep();
						u.display("Unrecognized id.\r\n");
						u.ledRedOn();
					} catch (Exception e) {
						reader.failBeep();
						u.display("Error retrieving\r\nuser details.");
					}
					Thread.sleep(2000);
					u.ledsOff();
					u.display("Please swipe your\r\nwristband...");
				} catch (StateUnchangedException e) {
				}
				Thread.sleep(200);
			}

		} catch (Exception e) {
			reader.stop();
			e.printStackTrace();
		}
	}

	/**
	 * Checkin mode
	 */
	public void runCheckIn() {
		System.out.println("Running checkIn mode");
		Set<String> tags;
		try {
			//
			// Monitor tags
			//
			u.bell();
			u.display("Please swipe your\r\nwristband...");

			while (true) {
				try {
					//
					// Get currently scanned tags
					//
					tags = reader.poll();
					u.display("Please wait..\r\n");
					
					try {
						String name = cache.getUserInfo(tags.iterator().next());
						c.checkInUser(tags, conf.getAttractionId(), conf.getAttractionName());
						reader.passBeep();
						u.ledGreenOn();
						u.display("Checkin successfull.\r\n" + name);

					} catch (UserNotFoundException e) {
						//
						// If user not found
						//
						reader.failBeep();
						u.display("Unrecognized id.\r\n");
						u.ledRedOn();
					} catch (Exception e) {
						e.printStackTrace();
						reader.failBeep();
						u.display("Error retrieving\r\nuser details.");
					}
					Thread.sleep(2000);
					u.ledsOff();
					u.display("Please swipe your\r\nwristband...");
				} catch (StateUnchangedException e) {
				}
				Thread.sleep(200);
			}

		} catch (Exception e) {
			reader.stop();
			e.printStackTrace();
		}
	}
	/**
	 * Creates an instance of DBCache
	 * Launches a new thread to refresh the cache every 5 minutes
	 */
	public void enableCache() {
		this.cache = new DBCache(this.c);
		Thread update = new Thread() {
			public void run() {
				while (true) {
					cache.refresh();
					try {
						Thread.sleep(300000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		update.start();
	}
}


